from flask import Blueprint
from flask import request
from flask import render_template
from flask import flash
from flask import redirect
from flask import url_for

from app import db

from app.security import g

from app.wtforms.comite_cambio_forms import ComiteEditable
from app.wtforms.comite_cambio_forms import ComiteConsultar

from app.models.comite_de_cambio import ComiteDeCambio
from app.models.usuario import Usuario



mod = Blueprint('comites', __name__, url_prefix='/comite')

@mod.route('/administracion/', methods=['GET', 'POST'])
def administracion_cdc():
    """
    Muestra en pantalla las operaciones que se pueden realizar con un comite de cambio:
    Crear, Modificar, Consultar. Esta pagina solo podra ser vista por el lider del proyecto
    en cuestion
    """
    # Si el usuario no tiene asociado ningun proyecto o no es lider del proyecto
    # con el que se logueo no se le permite ver la pagina
    if g.proyecto==None or g.user.id!=g.proyecto.lider_id:
        flash('No tiene permiso para ver esta pagina.')
        return redirect(url_for('acceso.home'))
        
    return render_template('comite_cambio/administracion_cdc.html')


@mod.route('/crear/', methods=['GET', 'POST'])
def crear_cdc():
    """
    Permita la creacion de un comite de cambio si es que este no existe aun en el proyecto.
    Lista los usuarios que pueden ser miembros, por defecto esta marcado el lider del proyecto
    quien es miembro obligatorio
    """
    # Si el usuario no tiene asociado ningun proyecto o no es lider del proyecto
    # con el que se logueo no se le permite ver la pagina
    if g.proyecto==None or g.user.id!=g.proyecto.lider_id:
        flash('No tiene permiso para ver esta pagina.')
        return redirect(url_for('acceso.home'))
    
    # Obtenemos el proyecto con el que ingreso el usuario
    proyecto_seleccionado = g.proyecto
    # Obtenemos el comite asociado a ese proyecto
    comite_existe = proyecto_seleccionado.comite
    
    # Si ya existe el comite, informamos al usuario y lo redirigimos a la pagina de administracion
    # de comite de cambio
    if comite_existe != None:
        flash("El proyecto ya cuenta con un comite de cambio")
        return redirect(url_for('comites.administracion_cdc'))
    
    # Si no existe un comite asociado al proyecto
    else:
        # Obtenemos el formulario
        form = ComiteEditable(request.form)
        # Obtnemos los miembros del proyecto
        miembros_proyecto = proyecto_seleccionado.miembros
        
        # Realizamos uns lista de los miembros del proyecto para mostrarle al usuario
        lista_miembros_proyecto = []
        for miembro in miembros_proyecto:
            lista_miembros_proyecto.append((miembro.id, miembro.nombre))
        
        # Mostramos la lista del miembros del proyecto al usuario
        form.miembros.choices = lista_miembros_proyecto
        
        # Validamos todos los datos ingresados al formulario por el usuario
        if form.validate_on_submit():
            
            # Obtenemos la cantidad de miembros que fueron seleccionados
            cantidad_miembros = len(form.miembros.data)
            # Si esa cantidad es par, informamos al usuario del problema y no le permitimos crear
            # el comite por lo que lo redirigimos a la pagina de creacion de comite
            if (cantidad_miembros%2) == 0:
                flash('La cantidad de miembros del comite debe ser impar')
                return redirect(url_for('comites.crear_cdc'))
            
            # Si el numero seleccionado de miembros para el nuevo comite es impar    
            else:
                
                # Verificamos si el lider el proyecto se encuentra entre los miembros seleccionados
                # Si es asi, se crea el nuevo comite de cambio
                if proyecto_seleccionado.lider_id in form.miembros.data:
                    
                    # Realizamos una lista con todos lo usuarios que fueron seleccionados como
                    # miembros del proyecto
                    lista_miembros = []
                    for miembro in form.miembros.data:
                        # Por cada miembro seleccionado, traemos su usuario de la base de datos
                        usuario_miembro = Usuario.query.filter_by(id=miembro).first()
                        lista_miembros.append(usuario_miembro)
                    
                    # Creamos el nuevo cmite con la observacion realizada por usuario y la lista
                    # de miembros seleccionados por el mismo    
                    comite = ComiteDeCambio(form.observacion.data, lista_miembros, cantidad_miembros)
                    # Guardamos el comite de cambio en la base de datos
                    db.session.add(comite)
                    db.session.commit()
                    
                    # Indicamos en el proyecto cual es su comite de cambio
                    proyecto_seleccionado.comite = comite
                    # Guardamos los cambios en la base de datos
                    db.session.add(proyecto_seleccionado)
                    db.session.commit()
                    
                    # Desplegamos un mensaje indicando el exito de la operacion al usuario
                    flash('El comite ha sido registrado con exito')
                    return redirect(url_for('comites.administracion_cdc'))
                
                # Si el lider del proyecto no esta entre los miembor seleccionados
                # no permitimos la creacion del comite de cambio y se lo indicamos al usuario
                else:
                    flash('El lider del proyecto debe ser miembro del comite')
                    return redirect(url_for('comites.crear_cdc'))
        
        # Mostramos por defecto seleccionado al lider del proyecto como miembro del comite
        form.miembros.data = [proyecto_seleccionado.lider_id]
        return render_template('comite_cambio/crear_cdc.html', form=form)

    
@mod.route('/modificar/', methods=['GET', 'POST'])
def modificar_cdc():
    """
    Permite la modificacion de los miembros de un comite de cambio, el lider de proyecto
    debe ser miembro siempre
    """
    # Si el usuario no tiene asociado ningun proyecto o no es lider del proyecto
    # con el que se logueo no se le permite ver la pagina
    if g.proyecto==None or g.user.id!=g.proyecto.lider_id:
        flash('No tiene permiso para ver esta pagina.')
        return redirect(url_for('acceso.home'))
    
    # Obtenemos el proyecto con el que ingreso el usuario
    proyecto_seleccionado = g.proyecto
    # Obtenemos el comite de cambio de ese proyecto
    comite_existe = proyecto_seleccionado.comite
   
    # Si no existe un comite de cambio asociado con el proyecto
    if comite_existe == None:
        # Se lo indicamos al usuario con un mensaje y lo redirigimos a la pagina de administracion
        # de comite de cambio
        flash("El proyecto no cuenta con un comite de cambio")
        return redirect(url_for('comites.administracion_cdc'))
    
    # Si existe un comite de cambio asociado con el proyecto
    else:
        # Obtenemos el formulario
        form = ComiteEditable(request.form)
        # Obtenemos lo miembros del proyecto
        miembros_proyecto = proyecto_seleccionado.miembros
        
        # Relizamos un lista de los miembros del proyecto para mostrarle al usuario
        lista_miembros_proyecto = []
        for miembro in miembros_proyecto:
            lista_miembros_proyecto.append((miembro.id, miembro.nombre))
        
        # Mostramos la lista de miembros del proyecto al usuario    
        form.miembros.choices = lista_miembros_proyecto
        
        lista_miembros_seleccionados = []
        for miembro in comite_existe.miembros:
            lista_miembros_seleccionados.append(miembro.id)
        
        # Validamos que los datos ingresados al usuario sean correctos
        if form.validate_on_submit():
            
            # Obtenemos la cantidad de miembros seleccionados por el usuario
            cantidad_miembros = len(form.miembros.data)
            # Si la cantidad seleccionada es par
            if (cantidad_miembros) != comite_existe.cantidad_miembros:
                # No se permite guardar los cambios. Se despliega un mensaje indicando al usuario
                # el hecho
                flash('La cantidad de miembros del comite debe ser %s' % comite_existe.cantidad_miembros )
                return redirect(url_for('comites.modificar_cdc'))
            
            # Si la cantidad de miembros seleccionados es impar    
            else:
                # Se verifica si el lider de proyecto esta seleccionado como miembro
                # Si lo esta, se realiza la modificacion
                if proyecto_seleccionado.lider_id in form.miembros.data:
                    
                    # Realizamos un lista con los miembros seleccionados por el usuario
                    lista_miembros = []
                    # Por cada miembro seleccionado
                    for miembro in form.miembros.data:
                        # Obtenemos su usuario de la base de datos y lo agregamos a la lista
                        usuario_miembro = Usuario.query.filter_by(id=miembro).first()
                        lista_miembros.append(usuario_miembro)
                    
                    # Cambiamos el valor de la observacion por la que ingreso el usuario    
                    comite_existe.observacion = form.observacion.data
                    # Cambiamos el los miembros del comite por los que selecciono el usuario
                    comite_existe.miembros = lista_miembros
                    # Guardamos los cambios en la base de datos
                    db.session.add(comite_existe)
                    db.session.commit()
                    
                    # Indicamos al usuario el exito de la operacion, desplegando un mensaje
                    flash('El comite ha sido registrado con exito')
                    return redirect(url_for('comites.administracion_cdc'))
                
                # Si el lider el proyecto no se encuentra como miembro del comite
                else:
                    # No permitimos su modificacion, indicamos al usuario el hecho desplegando
                    # un mensaje
                    flash('El lider del proyecto debe ser miembro del comite')
                    return redirect(url_for('comites.modificar_cdc'))
        
        # Mostramos al usuario la lista de miembros actuales el comite de cambio
        form.miembros.data = lista_miembros_seleccionados
        # Mostramos al usuario la observacion actual que posee el comite de cambio
        form.observacion.data = comite_existe.observacion
        return render_template('comite_cambio/modificar_cdc.html', form=form)


@mod.route('/consultar/', methods=['GET', 'POST'])
def consultar_cdc():
    """
        Consulta los miembros que forman el comite de cambio
    """
    # Si el usuario no tiene asociado ningun proyecto o no es lider del proyecto
    # con el que se logueo no se le permite ver la pagina
    if g.proyecto==None or g.user.id!=g.proyecto.lider_id:
        flash('No tiene permiso para ver esta pagina.')
        return redirect(url_for('acceso.home'))
    
    # Obtenemos el proyecto con el que ingreso el usuario
    proyecto_seleccionado = g.proyecto
    # Obtenemos el comite de cambio de ese proyecto
    comite_existe = proyecto_seleccionado.comite
   
    # Si no existe un comite de cambio asociado con el proyecto
    if comite_existe == None:
        # Se lo indicamos al usuario con un mensaje y lo redirigimos a la pagina de administracion
        # de comite de cambio
        flash("El proyecto no cuenta con un comite de cambio")
        return redirect(url_for('comites.administracion_cdc'))
    
    # Si existe un comite de cambio asociado con el proyecto
    else:
        # Obtenemos el formulario
        form = ComiteConsultar(request.form)
        # Obtenemos lo miembros del comite de cambio
        miembros_comite = comite_existe.miembros
        
        # Relizamos una lista de los miembros del comite para mostrar al usuario
        lista_miembros_comite = []
        for miembro in miembros_comite:
            lista_miembros_comite.append((miembro.id, miembro.nombre))
                
        # Validamos que los datos ingresados al usuario sean correctos
        if form.validate_on_submit():
            #Cuando el usuario presiona aceptar, redirigimos a la pagina de administracion de comite de cambios
            return redirect(url_for('comites.administracion_cdc'))        
        
        
        # Mostramos al usuario la lista de miembros actuales el comite de cambio
        form.miembros.choices = lista_miembros_comite
        return render_template('comite_cambio/consultar_miembroscdc.html', form=form)